package com.zhangyu.shadow.core.app;

import android.os.Handler;
import android.support.annotation.NonNull;

import com.joanzapata.iconify.IconFontDescriptor;
import com.joanzapata.iconify.Iconify;
import com.orhanobut.logger.LogAdapter;
import com.orhanobut.logger.Logger;
import com.zhangyu.shadow.core.delegate.web.event.Event;
import com.zhangyu.shadow.core.delegate.web.event.EventManager;
import com.zhangyu.shadow.core.util.Utils;
import com.zhangyu.shadow.core.util.log.ShadowLogger;

import java.util.ArrayList;
import java.util.HashMap;

import okhttp3.Interceptor;

/**
 * @author zhangyu
 * @date 2017/10/18
 */

public class Configurator {
    private static final HashMap<Object, Object> SHADOW_CONFIGS = new HashMap<>();
    private static final ArrayList<IconFontDescriptor> ICONS = new ArrayList<>();
    private static final ArrayList<Interceptor> INTERCEPTORS = new ArrayList<>();
    private static final ArrayList<LogAdapter> LOGGERS = new ArrayList<>();
    private static final Handler HANDLER = new Handler();

    private static final class Holder {
        private static final Configurator INSTANCE = new Configurator();
    }

    static Configurator getInstance() {
        return Holder.INSTANCE;
    }

    private Configurator() {
        SHADOW_CONFIGS.put(ConfigType.CONFIG_READY, false);
        SHADOW_CONFIGS.put(ConfigType.HANDLER, HANDLER);
    }

    public final void configure() {
        initIcons();
        initLoggers();
        initUtils();
        SHADOW_CONFIGS.put(ConfigType.CONFIG_READY, true);
    }

    private void initUtils() {
        Utils.init(Shadow.getApplication());
    }

    final HashMap<Object, Object> getShadowConfigs() {
        return SHADOW_CONFIGS;
    }

    public final Configurator withApiHost(String host) {
        SHADOW_CONFIGS.put(ConfigType.API_HOST, host);
        return this;
    }

    public final Configurator withIcon(IconFontDescriptor descriptor) {
        ICONS.add(descriptor);
        SHADOW_CONFIGS.put(ConfigType.ICON, ICONS);
        return this;
    }

    public final Configurator withInterceptor(Interceptor interceptor) {
        INTERCEPTORS.add(interceptor);
        SHADOW_CONFIGS.put(ConfigType.INTERCEPTOR, INTERCEPTORS);
        return this;
    }

    public final Configurator withWebEvent(@NonNull String name, @NonNull Event event) {
        EventManager.getInstance().addEvent(name, event);
        return this;
    }

    public final Configurator withWebHost(String host) {
        SHADOW_CONFIGS.put(ConfigType.WEB_HOST, host);
        return this;
    }

    public final Configurator withJavascriptInterface(@NonNull String name) {
        SHADOW_CONFIGS.put(ConfigType.JAVASCRIPT_INTERFACE, name);
        return this;
    }

    public final Configurator withInterceptors(ArrayList<Interceptor> interceptors) {
        INTERCEPTORS.addAll(interceptors);
        SHADOW_CONFIGS.put(ConfigType.INTERCEPTOR, INTERCEPTORS);
        return this;
    }

    public final Configurator withDelay(long delay) {
        SHADOW_CONFIGS.put(ConfigType.DELAY, delay);
        return this;
    }

    public final Configurator withLogger(LogAdapter adapter) {
        LOGGERS.add(adapter);
        SHADOW_CONFIGS.put(ConfigType.LOG, LOGGERS);
        return this;
    }

    public final Configurator withWeChatAppId(String appId) {
        SHADOW_CONFIGS.put(ConfigType.WE_CHAT_APP_ID, appId);
        return this;
    }

    public final Configurator withWeChatAppSecret(String appSecret) {
        SHADOW_CONFIGS.put(ConfigType.WE_CHAT_APP_SECRET, appSecret);
        return this;
    }

    private void initIcons() {
        if (!ICONS.isEmpty()) {
            final Iconify.IconifyInitializer initializer = Iconify.with(ICONS.get(0));
            for (int i = 1, j = ICONS.size(); i < j; i++) {
                initializer.with(ICONS.get(i));
            }
        }
    }

    private void initLoggers() {
        if (!LOGGERS.isEmpty()) {
            for (LogAdapter adapter : LOGGERS)
                Logger.addLogAdapter(adapter);
        }
    }

    private void checkConfiguration() {
        final boolean isReady = (boolean) SHADOW_CONFIGS.get(ConfigType.CONFIG_READY);
        if (!isReady) {
            throw new RuntimeException("Configuration is not ready,call configure");
        }
    }

    @SuppressWarnings("unchecked")
    final <T> T getConfiguration(Object key) {
        //checkConfiguration();
        final Object value = SHADOW_CONFIGS.get(key);
        if (value == null) {
            //throw new NullPointerException(key.toString() + "IS NULL");
            ShadowLogger.e("shadow",key.toString() + "IS NULL");
            return null;
        }else {
            return (T) SHADOW_CONFIGS.get(key);
        }
    }
}
